// 库
import React, {
  useCallback,
  useState,
  useEffect,
  useMemo,
  useRef,
} from "react";
import { Box, Paper } from "@mui/material";
import {
  redirect,
  useSubmit,
  Outlet,
  useLoaderData,
  useActionData,
  useNavigate,
} from "react-router-dom";
import { ThemeProvider } from "@mui/material/styles";

// 公共组件
import TopBar from "../../components/topBar/TopBar";
import {
  ColumnFlexBoxSC,
  LilySnack,
  Context,
} from "../../components/common/Common";
import { lilyTheme } from "../../styles/theme";
import ProgressDialog from "../../components/common/ProcessDialog";
import {
  formattedSearchData,
} from "../../components/advancedSearchButton/Common";

// api
import {
  getDarkMode,
  updateDarkMode,
  loginNickName,
  refreshLocalCache,
} from "../../api/userData";
import {
  searchAdvancedFullText,
  getAdvancedSearchData,
} from "../../api/searchLaw";
import { logoutUser } from "../../api/userLoginRegister";

// 其他组件
import LogoutDialog from "./LogoutDialog";
import RefreshLocalcacheDialogue from "./RefreshLocalcachDialog";
import { setSearchDataCache } from "../../localCache/searchCache";

/**
 * Loader for Root
 * @returns {object} various data to be used by Root component
 */
export async function loader() {
  const initDarkMode = getDarkMode();
  const userName = loginNickName();
  const advancedSearchResult = await getAdvancedSearchData();
  return { initDarkMode, userName, advancedSearchResult };
}

/**
 * Sign in action function
 * @param {request} request data
 * @returns redirect if successful, id if failed
 */
export async function action({ request }) {
  const formData = await request.formData();
  const type = formData.get("type");
  if (type === "logout") {
    await logoutUser();
    return redirect("/login");
  } else if (type === "refresh-local-cache") {
    // Refresh local cache
    const res = { type, location: window.location.pathname };
    res.err = await refreshLocalCache();
    return res;
  } else if (type === "advanced-search") {
    const formattedData = JSON.parse(formData.get("formattedData"));
    // console.log(formattedData);
    const res = { fail: true };
    res.err = await searchAdvancedFullText(formattedData);
    if (res.err.length > 0) {
      return res;
    } else {
      return redirect(`/fayucz/legislation`);
    }
  }
  return null;
}

/**
 * Root component
 * @module Root
 */
export default function Root() {
  /* ---------------------------------------------------------
   *                    Snackbar messages
   * ---------------------------------------------------------*/
  const [snackbarMes, setSnackbarMes] = useState({
    text: undefined,
    open: false,
    severity: "warning",
  });

  // Submit and action outcome
  const submit = useSubmit();

  //Get loader data
  const { initDarkMode, userName, advancedSearchResult } = useLoaderData();
  console.log(advancedSearchResult);

  /* ---------------------------------------------------------
   *                     Logout dialog
   * ---------------------------------------------------------*/
  // Dialog 的状态
  const [openLogoutDialog, setOpenLogoutDialog] = useState(false);

  // 处理 Dialog 的打开和关闭
  const handleLogoutDialog = useCallback(() => {
    setOpenLogoutDialog(true);
  }, []);
  const handleCloseLogoutDialog = useCallback(() => {
    setOpenLogoutDialog(false);
  }, []);

  // 处理登出
  const handleConfirmLogout = () => {
    // 关闭对话框
    handleCloseLogoutDialog();
    // 执行登出逻辑，例如清除令牌等
    submit(
      { type: "logout" },
      {
        method: "post",
      }
    );
  };
  /* ---------------------------------------------------------
   *                    Progress dialog
   * ---------------------------------------------------------*/
  const [progress, setProgress] = useState({
    loading: false,
    title: null,
  });
  /* ---------------------------------------------------------
   *                Refresh Localcache dialog
   * ---------------------------------------------------------*/
  const [openRefreshLocalcacheDialog, setOpenRefreshLocalcacheDialog] =
    React.useState(false);

  // Event handler for closing Refresh Localcache dialog button by backdropClick or escapekey
  const closeRefreshLocalcacheDialog = useCallback((e, reason) => {
    if (reason === "escapeKeyDown" || reason === "backdropClick") {
      setOpenRefreshLocalcacheDialog(false);
    }
  }, []);

  // Event handler for closing Refresh Localcache dialog button
  const handleCloseRefreshLocalcacheDialog = useCallback(() => {
    setOpenRefreshLocalcacheDialog(false);
  }, []);

  // Event handler for opening Refresh Localcache dialog button
  const handleRefreshLocalcacheDialog = useCallback(() => {
    setOpenRefreshLocalcacheDialog(true);
  }, []);
  /* ---------------------------------------------------------
   *                    dark mode states
   * ---------------------------------------------------------*/
  const [darkMode, setDarkMode] = useState(initDarkMode);

  // Handle dark/light mode switch -- another way is to do it in action
  const handleDark = useCallback(() => {
    // Update the darkMode state
    let newDarkMode = !darkMode;
    updateDarkMode(newDarkMode).then(setDarkMode(newDarkMode));
  }, [darkMode]);

  const wTheme = lilyTheme(darkMode);
  /* ---------------------------------------------------------
   *                Handle refresh cache result
   * ---------------------------------------------------------*/
  // Handle action outcome
  const navigate = useNavigate();
  const res = useActionData();
  useEffect(() => {
    if (res?.type === "refresh-local-cache") {
      if (res?.err === "") {
        setSnackbarMes({
          text: "刷新缓存成功",
          open: true,
          severity: "success",
        });
      } else if (res?.err?.length > 0) {
        setSnackbarMes({
          text: res.err,
          open: true,
          severity: "error",
        });
      }
      setProgress({ ...progress, loading: false });
      navigate(res.location);
    } else if (
      ["socket-update", "socket-reload", "logout"].includes(res?.type)
    ) {
      if (res?.err?.length > 0) {
        setSnackbarMes({
          text: res.err,
          open: true,
          severity: "error",
        });
      }
    }
  }, [res]);
  /* ---------------------------------------------------------
   *                        SearchBar
   * ---------------------------------------------------------*/
  //搜索框是否可见
  const [isVisible, setIsVisible] = useState(false);

  
  /* ---------------------------------------------------------
   *                    advanced Search
   * ---------------------------------------------------------*/
  //搜索条件，用于展示数据
  const [searchCondition, setSearchCondition] = useState([]);
  //检索要提交的数据
  const [searchData, setSearchData] = useState({});
  //维护一个变量，避免useEffect首次加载
  const isMounted = useRef(true); // 使用 useRef 来保持状态
  // 更新 isMounted 的值
  useEffect(() => {
    isMounted.current = true;
  }, []); // 空依赖数组表示这个 effect 只在组件挂载时运行一次

  
 /**
  * @param {object} submitData 都是传入的searchData
   * 提交数据,触发action
   */
 const handleSubmit = async (submitData) => {
  //TODO提交数据做有效性检查
  //格式化提交的数据
  const formattedData = formattedSearchData("submit", submitData);
  // 持久化存储
  await setSearchDataCache(searchData);
  submit(
    { type: "advanced-search", formattedData: JSON.stringify(formattedData) },
    { method: "post", encType: "application/x-www-form-urlencoded" }
  );
};

  /**
   * 监听searchData，来进行提交表单数据，侧边栏搜索、搜索栏搜索、高级搜索改变searchData
   * 从而进行提交数据
   */
  useEffect(() => {
    if (isMounted.current) {
      isMounted.current = false;
      return; // 首次渲染时退出
    }
    // 这里的代码将在 searchData 更新后执行    
    //格式化后用于展示的数据
    const formattedCondition = formattedSearchData("show", searchData);
    // 设置展示条件的状态
    setSearchCondition(formattedCondition);
    //对后端发起请求
    handleSubmit(searchData);
  }, [searchData]); // 依赖项数组中包括 searchData

    
  /* ---------------------------------------------------------
   *                         Context
   * ---------------------------------------------------------*/
  //创建context要传递的值
  const contextValue = useMemo(
    () => ({
      setSearchData,
      isVisible
    }),
    [isVisible]
  );

  return (
    <Context.Provider value={contextValue}>
      <ThemeProvider theme={wTheme}>
        {/* Use Paper for dark mode */}
        <Paper
          elevation={0}
          square={true}
          sx={{
            boxSizing: "border-box",
            minHeight: `calc(100vh)`,
            minWidth: "max-content",
            backgroundColor: (theme) => theme.palette.background.main,
            m: 0,
          }}
        >
          <ColumnFlexBoxSC>
            <ProgressDialog loading={progress.loading} title={progress.title} />
            <RefreshLocalcacheDialogue
              handleCloseRefreshLocalcacheDialog={
                handleCloseRefreshLocalcacheDialog
              }
              closeRefreshLocalcacheDialog={closeRefreshLocalcacheDialog}
              openRefreshLocalcacheDialog={openRefreshLocalcacheDialog}
              setProgress={setProgress}
            />
            <TopBar
              handleLogoutDialog={handleLogoutDialog}
              darkMode={darkMode}
              handleDark={handleDark}
              userName={userName}
              handleRefreshLocalcacheDialog={handleRefreshLocalcacheDialog}
            />
            {/* topBar buffer */}
            <Box
              sx={{
                pt: (theme) => theme.space.barHeight,
              }}
            />
            {/*渲染展示的页面 */}
            <Box
              sx={{
                pt: "1vh",
                width: "100%",
              }}
            >
              <ColumnFlexBoxSC
                sx={{
                  backgroundColor: (theme) => theme.palette.background.main,
                  width: "100%",
                  height: "auto",
                  px: "10%"
                }}
              >
                <Outlet
                  context={{
                    searchCondition,
                    setSearchCondition,
                    searchData,
                    handleSubmit,
                    advancedSearchResult,
                    setSearchData,
                    setIsVisible
                  }}
                />
              </ColumnFlexBoxSC>
            </Box>
            <div>
              {/* 登出确认对话框 */}
              <LogoutDialog
                openLogoutDialog={openLogoutDialog}
                setOpenLogoutDialog={setOpenLogoutDialog}
                handleConfirmLogout={handleConfirmLogout}
              />
            </div>
            <LilySnack
              duration={snackbarMes.duration}
              open={snackbarMes.open}
              onClose={(event, reason) => {
                if (reason === "clickaway") {
                  return;
                }
                setSnackbarMes({ ...snackbarMes, open: false });
              }}
              severity={snackbarMes.severity}
              text={snackbarMes.text}
            />
          </ColumnFlexBoxSC>
        </Paper>
      </ThemeProvider>
    </Context.Provider>
  );
}
